

/**
* @file GPSTK_CommonModels_CPP
* Class to convert CC(cross-correlation) to NONCC(non cross-correlation).
*/

//============================================================================
//  Function:
//
//  2019.4.25 s.j.zhang, modify 
//============================================================================

#include "CommonModels.hpp"


using namespace std;

#define debug 0

namespace gpstk
{

      // Return a string identifying this object.
    string CommonModels::getClassName() const
    { return "CommonModels"; }


    /** Return a gnssRinex object, adding the new data generated
     *  when calling this object.
     *
     * @param gData     Data object holding the data.
     */
    void CommonModels::Process(commonHeader& comHeader, gnssRinex& gRin)
        noexcept(false)
    {
        try
        {
               // Data preparing
            simFilter.Process(comHeader,gRin);
            dcbCorr.Process(comHeader,gRin);
            convertObs.Process(comHeader,gRin);
            requireObs.Process(comHeader,gRin);

               // Linear combinations and Linearize
            combs1.Process(comHeader,gRin);
            basicModel.Process(comHeader,gRin);

               // Systematic bias corrections
            eclipsedSV.Process(comHeader, gRin);
            gravDelay.Process(comHeader,gRin);
            satPCenter.Process(comHeader,gRin);
            computeTM.Process(comHeader,gRin);
            staTides.Process(comHeader,gRin);
            correctObs.Process(comHeader,gRin);

            // prefitIFCS
            prefitIFCS.Process(comHeader, gRin);

               // Cycle slip detection
            if(csMethod==1)
            {
                markCSMW12GPS.Process(comHeader,gRin);
                markCSLI12GPS.Process(comHeader,gRin);
                markCSLI15GPS.Process(comHeader,gRin);

                markCSMW15GAL.Process(comHeader,gRin);
                markCSLI15GAL.Process(comHeader,gRin);
                markCSLI17GAL.Process(comHeader,gRin);
                markCSLI18GAL.Process(comHeader,gRin);
                markCSLI16GAL.Process(comHeader,gRin);

                markCSMW27BDS.Process(comHeader,gRin);
                markCSLI27BDS.Process(comHeader,gRin);
                markCSLI26BDS.Process(comHeader,gRin);

                if(pLCDetector!=NULL)
                {
                    (*pLCDetector).Process(gRin);
                }

            }
            else if(csMethod==2)
            {
                if(pLCDetector!=NULL)
                {
                    (*pLCDetector).Process(gRin);
                }
                else
                {
                    cerr << "cycle slip detector must be given" << endl;
                    exit(-1);
                }
            }

            cout << "prefitIFCS" << endl;
            gRin.body.dump(cout,1);

            // cycle slip detection using DeltaLC
            markArc.Process(comHeader,gRin);

            cout << "markArc" << endl;
            gRin.body.dump(cout,1);
/*
            if(debug)
            {
                cout << "markArc" << endl;
                gRin.body.dump(cout,1);
            }
*/

            // warning, windUp need satArc information
            windUp.Process(comHeader,gRin);

            if(debug)
            {
                cout << "correctObs" << endl;
                gRin.body.dump(cout,1);
            }

               // align phase with code and recompute MW/LC
            phaseAlignGPSL1.Process(comHeader,gRin);
            phaseAlignGPSL2.Process(comHeader,gRin);

            combs2.Process(comHeader,gRin);

             
               // Prepare weight for estimation
            elevWeights.Process(comHeader,gRin);

            if(debug)
            {
                cout << "elevWeights" << endl;
                gRin.body.dump(cout,1);
            }

        }
        catch(InvalidRequest& e)
        {
            GPSTK_RETHROW(e);
        }
        catch(Exception& e)
        {
            GPSTK_RETHROW(e);
        }

    };


    /** Return a sourceRinex object, adding the new data generated
     *  when calling this object.
     *
     * @param gData     Data object holding the data.
     */
    void CommonModels::Process(commonHeader& comHeader, sourceRinex& sRin) 
    {

        if(debug)
        {
           cout << "before simFilter: " << endl;
           sRin.dump(cout, 1);
        }

           // Data preparing
        simFilter.Process(comHeader,sRin);
        dcbCorr.Process(comHeader,sRin);

/*
        requireObs.Process(comHeader,sRin);
*/

        if(debug)
        {
            cout << "after requireObs: " << endl;
            sRin.dump(cout, 1);
        }

        convertObs.Process(comHeader,sRin);

        if(debug)
        {
            cout << "after convert: " << endl;
            sRin.dump(cout, 1);
        }

           // please correct the ifcbs

           // Linear combinations and Linearize
        combs1.Process(comHeader,sRin);

        if(debug)
        {
            cout << "after comb1: " << endl;
            sRin.dump(cout, 1);
        }

        basicModel.Process(comHeader,sRin);

        if(debug)
        {
            cout << "after basic: " << endl;
            sRin.dump(cout, 1);
        }

           // Cycle slip detection
        markCSMW12GPS.Process(comHeader,sRin);
        markCSLI12GPS.Process(comHeader,sRin);
        markArc.Process(comHeader,sRin);

        if(debug)
        {
            cout << "after markCS: " << endl;
            sRin.dump(cout, 1);
        }


           // Systematic bias corrections
        eclipsedSV.Process(comHeader, sRin);
        gravDelay.Process(comHeader,sRin);
        satPCenter.Process(comHeader,sRin);
        windUp.Process(comHeader,sRin);
        computeTM.Process(comHeader,sRin);
        staTides.Process(comHeader,sRin);

        if(debug)
        {
            cout << "before corr: " << endl;
            sRin.dump(cout, 1);
        }

        correctObs.Process(comHeader,sRin);

        if(debug)
        {
            cout << "before phaseAlignGPSL1: " << endl;
            sRin.dump(cout, 1);
        }

  
           // align phase with code and recompute MW/LC
        phaseAlignGPSL1.Process(comHeader,sRin);
        phaseAlignGPSL2.Process(comHeader,sRin);


        combs2.Process(comHeader,sRin);

           // Prepare weight for estimation
        elevWeights.Process(comHeader,sRin);
         
/*
           //  Prefit-residuals 
        prefitPC.Process(comHeader,sRin);
        prefitLC.Process(comHeader,sRin);

        if(debug)
        {
            cout << "prefit: " << endl;
            sRin.dump(cout, 1);
        }
*/

    };



}  // End of namespace gpstk
